package com.qf.fmall2202.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qf.fmall2202.exception.QfException;
import com.qf.fmall2202.order.entity.OrderItem;
import com.qf.fmall2202.order.entity.Orders;
import com.qf.fmall2202.order.dao.OrdersDao;
import com.qf.fmall2202.order.service.OrderItemService;
import com.qf.fmall2202.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall2202.order.utils.OrderConstants;
import com.qf.fmall2202.order.vo.AddOrderReturnVo;
import com.qf.fmall2202.product.entity.ProductSku;
import com.qf.fmall2202.product.service.ProductSkuService;
import com.qf.fmall2202.shopcart.entity.ShoppingCart;
import com.qf.fmall2202.shopcart.service.ShoppingCartService;
import com.qf.fmall2202.utils.WxPayUtils;
import com.qf.fmall2202.vo.ResultVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author 徐英海
 * @since 2022-11-09
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersDao, Orders> implements OrdersService {
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private ProductSkuService productSkuService;
    @Autowired
    private OrderItemService orderItemService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo addOrders(String cids, Orders orders) {

        List<ShoppingCart> shoppingCartList = shoppingCartService.splitCidsToList(cids);
        checkStockNum(shoppingCartList);
        String skuNames = shoppingCartList.stream()
                .map(ShoppingCart::getSkuName)
                .collect(Collectors.joining(","));
        orders.setUntitled(skuNames);
        orders.setStatus(OrderConstants.ORDER_WAIT_TO_PAY);
        orders.setDeleteStatus(OrderConstants.ORDER_DEFAULT_DELETE_FLAG);
        orders.setCreateTime(new Date());
        orders.setUpdateTime(new Date());
        this.save(orders);//保存后自动回显id
        String orderId = orders.getOrderId();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        List<OrderItem> orderItemList = shoppingCartList.stream()
                .map(
                        cart -> {
                            OrderItem orderItem = new OrderItem();
                            orderItem.setOrderId(orderId);
                            //把cart中同名对象拷贝过来
                            BeanUtils.copyProperties(cart, orderItem);
                            orderItem.setBuyCounts(Integer.parseInt(cart.getCartNum()));
                            orderItem.setTotalAmount(BigDecimal.valueOf(cart.getSellPrice()).multiply(BigDecimal.valueOf(Integer.parseInt(cart.getCartNum()))));
                            orderItem.setBuyTime(new Date());
                            orderItem.setIsComment(0);
                            try {
                                orderItem.setBasketDate(simpleDateFormat.parse(cart.getCartTime()));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            return orderItem;
                        }
                ).collect(Collectors.toList());
        orderItemService.saveBatch(orderItemList);
        shoppingCartService.removeBatchByIds(shoppingCartList);
        //调用微信支付平台窗口，获取支付url
        String url = getWechatPayUrl(orderId);
        AddOrderReturnVo data = new AddOrderReturnVo(orderId, skuNames, url);
        return ResultVo.ok("添加成功", data);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String status(String orderId) {
        try {
            String result = WxPayUtils.queryOrder(orderId);
            if (result != null && result.equals(OrderConstants.PAY_OK)) {
                Orders orders = new Orders();
                orders.setOrderId(orderId);
                orders.setStatus(OrderConstants.PAY_OK_STATUS);
                orders.setUpdateTime(new Date());
                orders.setPayTime(new Date());
                this.updateById(orders);
                return OrderConstants.PAY_OK_STATUS;
            }
            return OrderConstants.PAY_NOT_OK_STATUS;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String getWechatPayUrl(String orderId) {
        try {
            return WxPayUtils.getPayUrl(orderId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 库存校验
     * 先合并skuId相同的数据，得到总购买数，然后进行库存比较
     *
     * @param shoppingCartList
     */
    private void checkStockNum(List<ShoppingCart> shoppingCartList) {
        Map<String, List<ShoppingCart>> skuIdMap = shoppingCartList.stream()
                .collect(Collectors.groupingBy(ShoppingCart::getSkuId));
        Set<Map.Entry<String, List<ShoppingCart>>> skuIdMapSet = skuIdMap.entrySet();
        for (Map.Entry<String, List<ShoppingCart>> entry : skuIdMapSet) {
            String skuId = entry.getKey();
            List<ShoppingCart> value = entry.getValue();
            Integer stockSum = value.stream()
                    .collect(Collectors.summingInt(cart -> Integer.parseInt(cart.getCartNum())));
            Integer skuStock = value.get(0).getStock();
            if (skuStock < stockSum) {
                throw new QfException("库存不足");
            }
            ProductSku productSku = new ProductSku();
            productSku.setSkuId(skuId);
            productSku.setStock(skuStock - stockSum);
            productSkuService.updateById(productSku);
        }
    }

}
